#ifndef GAMEMASTER_H
#define GAMEMASTER_H
#include "card.h"
#include "hand.h"
#include "Player.h"
#include <QTCore>
#include "Server.h"
#include"gamemaster.h"

//class created by NA Molapo,CP botha and AB Arakkal
/*!
 * \brief The GameMaster class a thread that is created by the server. This class runs the game and validates all moves made by players. All messages need to be passed through this class
 */
class GameMaster:public QThread
{
    private:
        /*!
         * \brief scores saves the scores of each player
         */
        int scores[4];
        /*!
         * \brief players a array of pointers to player objects
         */
        Player *players[4];
        /*!
         * \brief TrickWins saves the number of tricks won by each player
         */
        int TrickWins[4];
        /*!
         * \brief validateBid validates a QStringList containing the bid information
         * \return bool showing if bid was valid
         */
        bool validateBid(QStringList);
        /*!
         * \brief helperShuffle function used in suffling of cards
         * \param size
         * \param random
         * \param ids
         * \return
         */
        bool helperShuffle(int size,int random,int ids[]);
        /*!
         * \brief initializeDeck add all cards into a deck of cards
         */
        void initializeDeck();
        /*!
         * \brief validateHelper help the validate bid function by assigning a int value to a bid
         * \param b bid information in a QString
         * \return int value of a big
         */
        int validateHelper(QString b);
        /*!
         * \brief validateHelper2 help the validate bid function by assigning a int value to a bid
         * \param b bid information in a QString
         * \return int value of a big
         */
        int validateHelper2(QString b);
        /*!
         * \brief idShuffled array of shuffled ids
         */
        int *idShuffled; //array of shuffled ids
        /*!
         * \brief run function that runs the gamemaster thread
         */
        void run();
        /*!
         * \brief server is a pointer to a server object
         */
        Server * server;
        /*!
         * \brief ackCount counter that counts the acknowledges recieved
         */
        int ackCount;
        /*!
         * \brief highestBid QStringList that saves the information of the highest bid
         */
        QStringList highestBid;
        /*!
         * \brief redeal bool flag that shows if the game master needs to redeal
         */
        bool redeal;
        /*!
         * \brief highestBidPlayer is an int that saves the index of the player who made the highest bid
         */
        int highestBidPlayer;
        /*!
         * \brief currPlayer is an int of the player that is currently playing
         */
        int currPlayer;
        /*!
         * \brief firstPlayer is an int of the index of the player who needs to play first
         */
        int firstPlayer;
        /*!
         * \brief dummy pointer to the dummy player
         */
        Player * dummy;
        /*!
         * \brief trickNumber saves number of tricks played
         */
        int trickNumber;
        /*!
         * \brief dealNumber saves number of deals made
         */
        int dealNumber;
        /*!
         * \brief gameNumber saves number of games played
         */
        int gameNumber;
        /*!
         * \brief validateMove validates the moves made by players
         * \param Card object of the card that needs to be validated
         * \return bool indicating if the move was valid
         */
        bool validateMove(Card);
        /*!
         * \brief trick Hand object that contains the cards of the current trick
         */
        Hand *trick;
        /*!
         * \brief openingLead flag to show if the dummy has been opend
         */
        bool openingLead;
        /*!
         * \brief determineTrickWinner determine the current trick winner
         * \return QString containing the trick winner's information
         */
        QString determineTrickWinner();
        /*!
         * \brief winningTeam containing information of the team that won the last trick
         */
        QString winningTeam;
        /*!
         * \brief trumpSuit QChar containing the deal trump suit
         */
        QChar trumpSuit;
        /*!
         * \brief numUnder number of undertricks
         */
        int numUnder;   // number of undertricks
        /*!
         * \brief overT overtricks: ns[0]| ew[1]
         */
        int overT [2];   //
        /*!
         * \brief nsWonGames number of tricks won by team north south
         */
        int nsWonGames;
        /*!
         * \brief ewWonGames number of tricks won by team east south
         */
        int ewWonGames;
        /*!
         * \brief nsAbove scoreboard containing we above
         */
        QStringList nsAbove;
        /*!
         * \brief nsAbove scoreboard containing we below
         */
        QStringList nsBelow;
        /*!
         * \brief nsAbove scoreboard containing they above
         */
        QStringList ewAbove;
        /*!
         * \brief nsAbove scoreboard containing they below
         */
        QStringList ewBelow;
        /*!
         * \brief over bool flag for over trick
         */
        bool over;
        /*!
         * \brief trickWinner index of the player who won the last trick
         */
        int trickWinner;
        /*!
         * \brief trickMax pointer to the biggest card in the current trick
         */
        Card* trickMax;
        /*!
         * \brief gameDone bool flag to indicate if the game is done
         */
        bool gameDone;
        /*!
         * \brief gamesWon saves games won by the two teams
         */
        int gamesWon[2];

    public:
        /*!
         * \brief GameMaster contructor that takes a pointer to the server
         */
        GameMaster(Server *);        
        ~GameMaster();
        /*!
         * \brief shuffle start the shuffle of the cards
         */
        void shuffle();
        /*!
         * \brief deal the cards into four hands
         */
        void deal();
        /*!
         * \brief bidding handles the bidding phase
         */
        void bidding();
        /*!
         * \brief playing handles the playing phase
         */
        void playing();
        /*!
         * \brief UpdateTrickWinner update the last trick winner
         */
        void UpdateTrickWinner();
        /*!
         * \brief determineWinner determine the current trick winner
         * \return String containing current trick winner's username
         */
        string determineWinner();
        /*!
         * \brief validateMove validate last move made
         * \param leadSuit char of the current trick sut
         * \param h card object of played card
         * \param pos player index who played the card
         * \return bool
         */
        bool validateMove(char leadSuit,Card h,int pos);
        /*!
         * \brief determineScore function to help in determining the score
         */
        void determineScore();
        /*!
         * \brief print print the game master, for debugging
         */
        void print();
        /*!
         * \brief ack function gets called to acknowledges to game master
         */
        void ack();
        /*!
         * \brief setPlayerName set the player name at an index
         */
        void setPlayerName(int ,string);
        //Card *_cards;       // pointer to card
        /*!
         * \brief _hand pointer to a hand
         */
        Hand *_hand;
        /*!
         * \brief deck list that contains all the cards in a deck
         */
        list <Card> deck;
        //Hand *trick;  // to store trick =4 cards while playing
        /*!
         * \brief playerQuit function gets called when a player quits the game
         * \param name
         */
        void playerQuit(QString name);
};

#endif // GAMEMASTER_H
